package main

import (
	"gopkg.in/gomail.v2"
	"flag"
	"fmt"
	"os"
	"io/ioutil"
	"encoding/json"
)

func SendMail(host string,port int,from,password string,to,cc,attach []string,msg,subject string)error {
	var (
		toValue []string
		ccValue []string
	)

	m := gomail.NewMessage()

	fmt.Println("发件人地址:",from)
	for _, v := range to{
		if v == ""{
			continue
		}
		fmt.Println("收件人地址:",v)
		toValue = append(toValue,m.FormatAddress(v,"收件人"))
	}

	for _, v := range cc{
		if v == ""{
			continue
		}
		fmt.Println("抄送人地址:",v)
		ccValue = append(ccValue,m.FormatAddress(v,"收件人"))
	}

	m.SetAddressHeader("From",from,"发件人")
	m.SetHeader("To",toValue...)
	m.SetHeader("Cc",ccValue...)

	if subject != ""{
		m.SetHeader("Subject",subject)
	}
	if msg != ""{
		m.SetBody("text/plain",msg)
	}
	for _, v := range attach{
		if v == ""{
			continue
		}
		m.Attach(v)
	}

	d := gomail.NewDialer(host,port,from,password)
	return d.DialAndSend(m)
}
var (
	conf = flag.String("conf","conf.json","-conf conf_name")
	host = flag.String("host","smtp.163.com","host")
	port = flag.Int("port",25,"port")
	username = flag.String("u","","username")
	password = flag.String("p","","password")
	receive = flag.String("r","","receive")
	cc = flag.String("c","","carbon copy") //抄送
	attach = flag.String("a","","attach") //附件
	msg   = flag.String("m","","msg")
	subject   = flag.String("s","","subject")
	help = flag.Bool("h",false,"help")
	usage =
`使用方法: %s [选项......]
选项:
   	-conf   : 配置文件,从配置文件里读取参数,以下的参数都不用配置
   	-host   : 邮件服务商地址,默认为:smtp.163.com
   	-port   : 邮件服务商地址端口,默认为:25
	-u(必填) : 发件人的邮箱地址,如:sender@163.com
	-p(必填) : 发件人的邮箱密码或授权码,如:password
	-r(必填) : 收件人邮箱地址,如:receiver@163.com
	-c   	: 抄送收件人的邮箱地址,如:carbon_copy@163.com
	-a      : 附件,附件地址，如:当前目录下的txt文件, attach.txt
	-m      : 邮件内容,如:hello, i am a good man,and you?
	-s      : 邮件主题,如:论学习的重要性
	-h      : 显示本帮助内容
`)
func main() {
	flag.Usage = func() {
		fmt.Fprint(os.Stderr, fmt.Sprintf(usage, os.Args[0]))
	}
	flag.Parse()
	if *help{
		usageAndExit("")
	}
	if *conf != ""{
		type Email struct {
			Host string `json:"host"` //邮箱服务商的地址,如:smtp.163.com
			Port int `json:"port"` //邮箱服务商的端口,如:25
			Username string `json:"username"` //发件人邮箱地址(必填)
			Password string `json:"password"` //发件人邮箱密码(必填)
			Receiver []struct{  //收件人邮箱地址(必填),至少填写一个
				Addr string `json:"addr"`
			} `json:"receiver"`
			CarbonCopy []struct{ //抄送给某某的邮箱地址(非必填),可填一个或多个
				Addr string `json:"addr"`
			} `json:"carbon_copy"`
			Attachment []struct{ //邮件附件(非必填),可填一个或多个
				Filename string `json:"filename"`
			} `json:"attachment"`
			Msg string `json:"msg"`  //邮件内容(非必填),但建议填
			Subject string `json:"subject"` //邮件主题(非必填),但建议填
		}
		data, err := ioutil.ReadFile(*conf)
		if err != nil{
			fmt.Println(err)
			return
		}
		var e Email
		err = json.Unmarshal(data,&e)
		if err != nil{
			fmt.Println(err)
			return
		}
		var cc,to,attach []string
		for _, v := range e.Receiver{
			to = append(to,v.Addr)
		}
		for _, v := range e.CarbonCopy{
			cc = append(cc,v.Addr)
		}
		for _, v := range e.Attachment{
			attach = append(attach,v.Filename)
		}

		err = SendMail(e.Host,e.Port,e.Username,e.Password,to,cc,attach,e.Msg,e.Subject)
		if err != nil{
			fmt.Println(err)
		}else{
			fmt.Println("邮件发送成功")
		}
	}else {
		if *username == "" {
			usageAndExit("发件人邮箱地址必填")
		}
		if *password == "" {
			usageAndExit("发件人邮箱密码必填")
		}
		if *receive == "" {
			usageAndExit("收件人邮箱地址必填")
		}
		err := SendMail(*host,*port,*username, *password, []string{*receive}, []string{*cc}, []string{*attach}, *msg, *subject)
		if err != nil {
			fmt.Println(err)
		} else {
			fmt.Println("邮件发送成功")
		}
	}
}

func usageAndExit(msg string) {
	if msg != "" {
		fmt.Fprintf(os.Stderr, msg)
		fmt.Fprintf(os.Stderr, "\n\n")
	}
	flag.Usage()
	fmt.Fprintf(os.Stderr, "\n")
	os.Exit(1)
}